import { DispImpl } from '@movinliao/h5-events'

const kConnect = 'connectSignal'

const Root = DispImpl.extend(function () {
  var self = this
  var _root = null
  var _connect = null
  var _key = null
  var _module = null
  var _methods = []
  var _signals = []
  var _connects = {}

  var doExcute = function (key, args, nolog) {
    var method = _root && (key in _root) && _root[key]
    var result = null
    if (!method || (typeof method !== 'function')) {
      !nolog && self.log('===api:excute:' + key + ':methoderror===', 0)
      return result
    }
    try {
      result = method.apply(_root, args)
      !nolog && self.log('===api:excute:' + key + ':success===', 0)
    } catch (error) {
      !nolog && self.log('===api:excute:' + key + ':catcherror===', 0)
      // if (__DEV__) {
      //   throw (error)
      // }
      result = null
    }
    return result
  }

  var connectSignal = function (key, listener, nolog) {
    var result = null
    var signal = (_root && _root[key]) || null
    if (signal && listener && _connect) {
      if (_connects[key]) {
        _connects[key].disconnect && _connects[key].disconnect()
        delete _connects[key]
      }
      try {
        result = _connect(signal, function () {
          listener.apply(null, arguments)
        })
        _connects[key] = result
        !nolog && self.log('===api:connectSignal:' + key + ':success===', 0)
      } catch (error) {
        result = null
        !nolog && self.log('===api:connectSignal:' + key + ':catcherror===', 0)
        // if (__DEV__) {
        //   throw (error)
        // }
      }
    }
    return result
  }

  var doInit = function (key) {
    // if (typeof window === 'undefined') return;
    // (root in window) && (_root = window[root]);
    (kConnect in window) && (_connect = window[kConnect])
    _root && key && (key in _root) && (_root = _root[key])
  }

  this.constructor = function (root, key) {
    _key = key
    _root = root
    this.super(_key)
  }
  /**
     * 模块初始化
     * @param api
     */
  this.init = function (mod, methods, signals) {
    _module = mod
    _methods = methods || []
    _signals = signals || []
    doInit(_key)
  }
  /**
     *模块销毁
     */
  this.destroy = function () {
    self.disconnect()
    _root = null
    _connect = null
    _key = null
    _module = null
    _methods = []
    _signals = []
  }
  /**
     *停止
     */
  this.stop = function () {
    self.setPaused(true)
  }
  /**
     *开始
     */
  this.start = function () {
    self.setPaused(false)
  }

  this.excute = function (method, args, nolog) {
    return doExcute(method, args, nolog)
  }

  this.onSignal = function (signal, listener, nolog) {
    return connectSignal(signal, listener, nolog)
  }

  this.connectSignal = function (signal, listener) {
    var result = null
    if (signal && listener && _connect) {
      if (_connects[signal]) {
        _connects[signal].disconnect && _connects[signal].disconnect()
        delete _connects[signal]
      }

      result = _connect(signal, function () {
        listener.apply(null, arguments)
      })

      _connects[signal] = result
    }
    return result
  }

  this.log = function (content, tag) {
    _module && ('log' in _module) && _module.log(_key + ':' + content, tag)
  }

  this.disconnect = function () {
    for (var key in _connects) {
      var signal = _connects[key]
      signal && signal.disconnect()
    }
    _connects = {}
  }

  this.methods = function () {
    return _methods
  }

  this.signals = function () {
    return _signals
  }
})

export default Root
